iT邦幫忙

2022 iThome 鐵人賽

DAY 7
0
自我挑戰組

laravel+vue 學習系列 第 7

Day7. 補充 Blade

  • 分享至 

  • xImage
  •  

一、元件(Conpoment)與槽(slot)

  • Laravel 5.4 版本後加入
  • 提供另一種納入內的方法
  • 基本用法 @component 指令與 $slot 變數
    <!-- detail_modal.blade.php -->
    <div class="modal">	
        <div>
            {{ $slot }}
        </div>
        <div>加入購物車</div>
    </div>
    
    <!-- 在其他模板中引入 -->
    <!-- product_list.blade.php -->
    @foreach ( $products as $product )
        @component('product.detail_modal')
            商品詳細內容
        @endcomponent
    @endforeah
  • 多個插槽
    • 使用 @slot 指定非預設插槽內容
    • 其餘部分會放入預設插槽
        <!-- detail_modal.blade.php -->
        <div class="modal">	
            <h2>{{ $title }}</h2>
            <div>
                {{ $slot }}
            </div>
            <div>加入購物車</div>
        </div>
    
        <!-- product_list.blade.php -->
        @foreach ( $products as $product )
            @component('product.detail_modal')
                @slot('title')
                    這是商品名稱
                @endslot
                <p>商品詳細內容</p>
            @endcomponent
        @endforeah
    
        <!-- 若有要傳入的參數是陣列或物件, 可在第二個參數設定 -->
        @foreach ( $products as $product )
            @component('product.detail_modal', ['coupons', $product->$coupons])
                @slot('title')
                    這是商品名稱
                @endslot
                <p>商品詳細內容</p>
            @endcomponent
        @endforeah
    

二、將元件更名為指令

* e.g. @component('product.detail_modal') -> @detail_modal
* 可以使用 Blade::component() 靜態方法,常在 AppServiceProvider 的 boot() 方法執行
```php
    # 第一個參數為模板位置, 第二個參數是要產生的指令名稱
    Blade::component('product.detail_modal', 'myProductDetail')
    
    # 使用
    @myProductDetail
        # 內容...
    @endmyProductDetail
```

三、 view Composer 與服務注入

  • 定義當使用到特定 view 時, 必須載入相關使用到的資料, e.g. 導覽列載入設定好的項目
  • 避免每個 route() 或 redirect() 時都必須 with(), 手動添加資料
  • 使用全域共用變數
    # 在服務供應器 boot() 方法內設定
    public function boot() {
        # 設定 mainMenu 變數抓取主導覽內容
        view()->share('mainMenu', Menu::get('main'));
    }
  • 使用 Closure 設定
    # 單一模板綁定
    view()->composer('component.menu', function($view){
        $view->with('mainMenu', Menu::get('main'));
    });
    
    # 多模板綁定
    view()->composer(['component.menu', 'component.footer_menu'], function($view){
        $view->with('mainMenu', Menu::get('main'));
    });
    
    # 以 * 綁定多模板
    view()->composer('component.*', function($view){
        $view->with('mainMenu', Menu::get('main'));
    });
  • 建立類別使用 view composer
    # 建立 Class, 建議位置在 App\Http\ViewComposer
    namespace App\Http\ViewComposers;
    use App\Models\Menu;
    use Illuminate\Contracts\View\View;
    
    Class MenuComposer{
        public function compose(View $view) {
            $view->with('mainMenu', Menu::get('main'));
        }
    }
    
    # 設定在服務提供內
    # 與 Closure 用法類似, 只是要傳遞一個 Class 給方法
    public function boot(){
        view()->composer(
            'component.menu',
            \App\Http\ViewComposer\MenuComposer::class
        );
    } 

四、Blade 服務注入

  • 透過 typehint 注入
    Route::get('product/list', function( ProductCollection $products ) {
        return view('product.list')->with('products', $products);
    });
  • 使用 @inject 指令
    @inject('products', 'App\Services\Products');
    
    <div>
        總筆數: {{ $products->count }}
    </div>

自訂 Blade 指令

    # 通常會寫在 boot 內
    public function boot(){
        Blade::directive('ifProduct', function(){
            # 回傳一個 PHP 字串
            return "<?php if ( product()->getCount() ): ?>";
            
            # Blade 指令會產生快取, 不要用固定值回傳
            # $productCnt = product()->geteCount();
            # 這樣會造成回傳可能是快取的結果, 不是即時更新
            # return "<?php if ( $productCnt ) : ?>";
        });
    }
    
    # 帶入參數
    public function boot(){
        Blade::directive('ifProduct', function($category_id){
            # 回傳一個 PHP 字串
            return "<?php if ( product($category_id)->getCount() ): ?>";
        });
    }
    
    # 簡化自訂 if 指令
    public function boot(){
        Blade::if('ifProduct', function($category_id){
            # 回傳一個 PHP 字串
            return product($category_id)->getCount() > 0;
        });
    }

上一篇
Day6. Blade
下一篇
Day8. Laravel Mix
系列文
laravel+vue 學習32
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言